package lia.common;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.Collector;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Scorer;

/**
 * AllDocCollector: Gathers all documents from a search.
 * 
 * @author F.H Dragon(wenlong.meng@gmail.com)
 * @version 1.0 at 2011/08/07
 * @since 1.0
 */
public class AllDocCollector extends Collector {
	
	//local variables
	/**
	 * scorer
	 */
	private Scorer scorer;
	/**
	 * docBase
	 */
	private int docBase;
	/**
	 * docs
	 */
	List<ScoreDoc> docs = new ArrayList<ScoreDoc>();

	/**
	 * Called before successive calls to {@link #collect(int)}. Implementations
	 * that need the score of the current document (passed-in to
	 * {@link #collect(int)}), should save the passed-in Scorer and call
	 * scorer.score() when needed.
	 * 
	 * @param scorer to scorer to set
	 * @see org.apache.lucene.search.Collector#setScorer(org.apache.lucene.search.Scorer)
	 */
	@Override
	public void setScorer(Scorer scorer) throws IOException {
		this.scorer = scorer;
	}

	/**
	 * Called once for every document matching a query, with the unbased document
	 * number.
	 * 
	 * <p>
	 * Note: This is called in an inner search loop. For good search performance,
	 * implementations of this method should not call {@link Searcher#doc(int)} or
	 * {@link org.apache.lucene.index.IndexReader#document(int)} on every hit.
	 * Doing so can slow searches by an order of magnitude or more.
	 * 
	 * @param doc - Create absolute docID: doc + docBase
	 * @see org.apache.lucene.search.Collector#collect(int)
	 */
	@Override
	public void collect(int doc) throws IOException {
		//record score
		this.docs.add(new ScoreDoc(doc + docBase, scorer.score()));
	}

	/**
	 * Called before collecting from each IndexReader. All doc ids in
	 * {@link #collect(int)} will correspond to reader.
	 * 
	 * Add docBase to the current IndexReaders internal document id to re-base ids
	 * in {@link #collect(int)}
	 * 
	 * @param reader next IndexReader
	 * @param docBase 
	 * @see org.apache.lucene.search.Collector#setNextReader(org.apache.lucene.index.IndexReader, int)
	 */
	@Override
	public void setNextReader(IndexReader reader, int docBase)
			throws IOException {
		this.docBase = docBase;
	}

	/**
	 * Return <code>true</code> if this collector does not
	 * require the matching docIDs to be delivered in int sort
	 * order (smallest to largest) to {@link #collect}.
	 * 
	 * @see org.apache.lucene.search.Collector#acceptsDocsOutOfOrder()
	 */
	@Override
	public boolean acceptsDocsOutOfOrder() {
		return true;
	}
	
	/**
	 * Removes all of the elements from docs.
     * The dosc will be empty after this call returns.
	 */
	public void reset(){
		this.docs.clear();
	}
	
	/**
	 * Returns all of the elements from docs.
	 * 
	 * @return
	 */
	public List<ScoreDoc> getHits(){
		return this.docs;
	}

}
